package com.hermit.qmst.tools;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.LruCache;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by hermithermit on 15/3/10.
 */


/**
 * 图片下载器
 *
 * @author peidongxu
 *
 */
public class ImageDownLoader {
    /**
     * 缓存Image的类，当存储Image的大小大于LruCache设定的值，系统自动释放内存
     */
    private LruCache<String, Bitmap> mMemoryCache;
    /**
     * 操作文件相关类对象的引用
     */
    private FileUtils fileUtils;
    /**
     * 下载Image的线程池
     */
    private ExecutorService mImageThreadPool = null;

    private Context context;

    /**
     * 文件一共的大小
     */
    private int fileSize = 0;
    /**
     * 已经下载的大小
     */
    private int downloadSize = 0;
    /**
     * 已经下载的大小
     */
    private Handler handler;

    public ImageDownLoader(Context context) {
        this.context = context;
        // 获取系统分配给每个应用程序的最大内存，每个应用系统分配32M
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int mCacheSize = maxMemory / 8;
        // 给LruCache分配1/8 4M
        mMemoryCache = new LruCache<String, Bitmap>(mCacheSize) {

            // 必须重写此方法，来测量Bitmap的大小
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes() * value.getHeight();
            }

        };

        fileUtils = new FileUtils();
    }

    public ImageDownLoader(Context context, Handler handler) {
        this.context = context;
        this.handler = handler;
        // 获取系统分配给每个应用程序的最大内存，每个应用系统分配32M
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int mCacheSize = maxMemory / 8;
        // 给LruCache分配1/8 4M
        mMemoryCache = new LruCache<String, Bitmap>(mCacheSize) {

            // 必须重写此方法，来测量Bitmap的大小
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes() * value.getHeight();
            }

        };

        fileUtils = new FileUtils();
    }

    /**
     * 获取线程池的方法，因为涉及到并发的问题，我们加上同步锁
     *
     * @return
     */
    public ExecutorService getThreadPool() {
        if (mImageThreadPool == null) {
            synchronized (ExecutorService.class) {
                if (mImageThreadPool == null) {
                    // 为了下载图片更加的流畅，我们用了2个线程来下载图片
                    mImageThreadPool = Executors.newFixedThreadPool(2);
                }
            }
        }

        return mImageThreadPool;

    }

    /**
     * 添加Bitmap到内存缓存
     *
     * @param key
     * @param bitmap
     */
    public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null && bitmap != null) {
            mMemoryCache.put(key, bitmap);
        }
    }

    /**
     * 从内存缓存中获取一个Bitmap
     *
     * @param key
     * @return
     */
    public Bitmap getBitmapFromMemCache(String key) {
        return mMemoryCache.get(key);
    }

    /**
     * 下载图片, 保存
     *
     * @param url
     * @return
     */
    public void downloadImage(final String fileDir, final String url) {
        // 替换Url中非字母和非数字的字符,用Url作为文件名
        final String imageType = url.substring(url.length() - 3).toUpperCase();
        final String fileName = url.replaceAll("[^\\w.]", "");

        getThreadPool().execute(new Runnable() {

            @Override
            public void run() {
                // 下载
                try {

                        Bitmap bitmap = getBitmapFormUrl(url);
                        // 图片
                        fileUtils.savaBitmap(fileDir,fileName, bitmap,imageType);
                        // 将Bitmap 加入内存缓存
                        addBitmapToMemoryCache(fileName, bitmap);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 先从内存缓存中获取Bitmap,如果没有就从SD卡或者手机缓存中获取，SD卡或者手机缓存 没有就去下载
     *
     * @param url
     *            图片链接

     * @param listener
     * @return
     */
    public Bitmap downloadImage(final String fileDir, final String url, final onImageLoaderListener listener) {
        if (url == null || "".equals(url)) {
            return null;
        }


        final String imageType = url.substring(url.length() - 3).toUpperCase();
        final String fileName = url.replaceAll("[^\\w.]", "");
        Bitmap bitmap = showCacheBitmap(fileDir,fileName);
        if (bitmap != null) {
            Log.i("ImageDownLoader","从手机或缓存下载图片",true);
            return bitmap;
        } else {
            final Handler handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    listener.onImageLoader((Bitmap) msg.obj, url);
                }
            };
            getThreadPool().execute(new Runnable() {

                @Override
                public void run() {
                    Bitmap bitmap = getBitmapFormUrl(url);

                    Log.i("ImageDownLoader","从网上下载图片",true);

                    Message msg = handler.obtainMessage();
                    msg.obj = bitmap;
                    handler.sendMessage(msg);

                    try {
                        // 保存在SD卡或者手机目录
                        fileUtils.savaBitmap(fileDir,fileName, bitmap,imageType);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    // 将Bitmap 加入内存缓存
                    addBitmapToMemoryCache(fileName, bitmap);
                }
            });
        }

        return null;
    }


    /**
     * 获取Bitmap, 内存中没有就去手机或者sd卡中获取，这一步在getView中会调用，比较关键的一步
     *
     * @param url
     * @return
     */
    public Bitmap showCacheBitmap(String fileDir, String url) {
        if (getBitmapFromMemCache(url) != null) {



            return getBitmapFromMemCache(url);
        } else if (fileUtils.isFileExists(fileDir, url) && fileUtils.getFileSize(fileDir,url) != 0) {
            // 从SD卡获取手机里面获取Bitmap
            Bitmap bitmap = fileUtils.getBitmap(fileDir,url);

            // 将Bitmap 加入内存缓存
            addBitmapToMemoryCache(url, bitmap);
            return bitmap;
        }

        return null;
    }

    /**
     * 根据URL得到输入流
     *
     * @param urlstr
     * @return
     */
    public InputStream getInputStreamFormUrl(String urlstr) {
        InputStream inputStream = null;
        try {
            URL url = new URL(urlstr);
            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
            inputStream = urlConn.getInputStream();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return inputStream;
    }

    /**
     * 从Url中获取Bitmap
     *
     * @param url
     * @return
     */
    private Bitmap getBitmapFormUrl(String url) {
        Bitmap bitmap = null;
        HttpURLConnection con = null;
        InputStream is = null;
        try {
            // URL mImageUrl = new URL(url);
            // con = (HttpURLConnection) mImageUrl.openConnection();
            // con.setConnectTimeout(2 * 5000);
            // con.setReadTimeout(6 * 5000);
            // con.setDoInput(true);
            // con.setDoOutput(true);
            // bitmap = BitmapFactory.decodeStream(con.getInputStream());
            URL mImageUrl = new URL(url);
            is = mImageUrl.openStream();
            bitmap = BitmapFactory.decodeStream(is);
        } catch (Exception e) {
            e.printStackTrace();
        }catch (OutOfMemoryError oe){

            if (bitmap != null && !bitmap.isRecycled()){
                bitmap.recycle();
            }
        }

        finally {
            if (con != null) {
                con.disconnect();
            }
        }
        return bitmap;
    }



    /**
     * 给hand发送消息
     *
     * @param what
     */
    private void sendMessage(int what) {
        Message m = new Message();
        m.what = what;
        handler.sendMessage(m);
    }

    /**
     * 取消正在下载的任务
     */
    public synchronized void cancelTask() {
        if (mImageThreadPool != null) {
            mImageThreadPool.shutdownNow();
            mImageThreadPool = null;
        }
    }

    /**
     * 异步下载图片的回调接口
     *
     * @author len
     *
     */
    public interface onImageLoaderListener {
        void onImageLoader(Bitmap bitmap, String url);
    }


}
